package com.atguigu.tingshu.user.service.impl;

import com.atguigu.tingshu.common.config.config.RabbitConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.common.util.MongoUtil;
import com.atguigu.tingshu.model.user.UserListenProcess;
import com.atguigu.tingshu.user.service.UserListenProcessService;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.atguigu.tingshu.vo.user.UserListenProcessVo;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.A;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserListenProcessServiceImpl implements UserListenProcessService {

	@Autowired
	private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;


    @Override
    public BigDecimal getTrackBreakSecond(Long trackId) {
        Long userId = AuthContextHolder.getUserId();
        //根据用户id、声音获取播放进度
        Query query = Query.query(Criteria.where("userId").is(userId).and("trackId").is(trackId));
        //根据用户id计算该用户的播放进度应该存放的合计
        String collectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS,userId);
        //查询
        UserListenProcess userListenProcess = mongoTemplate.findOne(query, UserListenProcess.class, collectionName);

        if (userListenProcess!=null){
            //获取播放到的跳出时间
        return userListenProcess.getBreakSecond();

        }


        return new BigDecimal("0");
    }

    @Override
    public void updateListenProcess(UserListenProcessVo processVo) {
        Long trackId = processVo.getTrackId();
        Long userId = AuthContextHolder.getUserId();
        //根据 用户id和声音id查询播放进度
        Query query = Query.query(Criteria.where("userId").is(userId).and("trackId").is(trackId));
        //获取播放进度应该存放的集合
        String collectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId);
        //查询登录用户当前声音播放进度
        UserListenProcess userListenProcess = this.mongoTemplate.findOne(query, UserListenProcess.class, collectionName);
        if (userListenProcess!=null){
            //更新播放进度
            userListenProcess.setBreakSecond(processVo.getBreakSecond());
            userListenProcess.setUpdateTime(new Date());
        }else {
            //初始化播放进度对象，保存播放进度
            userListenProcess = new UserListenProcess();
            BeanUtils.copyProperties(processVo,userListenProcess);

            //初始化数据
            userListenProcess.setUserId(userId);
            userListenProcess.setId(ObjectId.get().toString());
            userListenProcess.setIsShow(1);
            userListenProcess.setCreateTime(new Date());
            userListenProcess.setUpdateTime(userListenProcess.getUpdateTime());


        }
        this.mongoTemplate.save(userListenProcess,collectionName);

        //判断是否统计过声音播放次数  同一个用户一天统计一次
        String key = "user:track:"+ new DateTime().toString("yyyy-MM-dd")+":"+userId;
        Boolean isExist = this.redisTemplate.opsForValue().getBit(key, trackId);
        //如果不存在则统计存在则不统计
        if (!isExist){
            //这里统计使用的是mq发送消息 异步解耦合

            //向redis标记 已统计  使用的是redis的bitMap结构
            this.redisTemplate.opsForValue().setBit(key,trackId,true);
            //设置过期时间， 过期时间= 明天凌晨-当前时间
            LocalDateTime nextDay = LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.MIN);//明日陵城
            long expireTime = ChronoUnit.SECONDS.between(LocalTime.now(), nextDay); //计算过期时间 使用的ChronoUnit
            this.redisTemplate.expire(key,expireTime, TimeUnit.SECONDS);

            //组装消息
            TrackStatMqVo trackStatMqVo = new TrackStatMqVo();
            trackStatMqVo.setBusinessNo(IdWorker.getIdStr());
            trackStatMqVo.setAlbumId(userListenProcess.getAlbumId());
            trackStatMqVo.setTarckId(trackId);
            trackStatMqVo.setStatType(SystemConstant.TRACK_STAT_PLAY);
            trackStatMqVo.setCount(1);
            rabbitTemplate.convertAndSend(RabbitConstant.USER_EXCHANGE,RabbitConstant.USER_STAT_RK,trackStatMqVo);


        }

    }
}
